package x10.eventServices;

import java.util.HashMap;
import java.util.logging.Logger;

import x10.enums.Interfaces;
import x10.event.X10Event;
import x10.eventServices.gui.GUIManager;
import x10.eventServices.log.EventLogger;
import x10.eventServices.tcp.TCPConnectionManager;
import x10.interfaces.cm15a.CM15A;
import x10.properties.PropertiesManager;

/**
 * @author Denny Sheirer
 * @date   2011
 */
public class EventServiceManager implements X10EventListener{
    String eventListenerName = "EventServiceManager";
    private Logger logger = Logger.getLogger("x10.eventServices.EventServiceManager");
    PropertiesManager properties = new PropertiesManager();
    HashMap<String, X10EventListener> eventServices = new HashMap<String, X10EventListener>();
    
    public EventServiceManager(){
    }

    /**
     * receiveEvent() - implementation of the X10EventListener interface
     * The EventServiceManager broadcasts the received X10Event to each of
     * the enabled EventServices
     * 
     * @param event - X10Event to be broadcast to all registered X10EventListeners
     */
    public synchronized void receiveEvent(X10Event event){
	//Broadcast the event to each of the enabled event services
	for(X10EventListener service: eventServices.values()){
	    service.receiveEvent(event);
	}
    }

    /**
     * getEventListenerName() - returns the name of this X10EventListener class
     */
    public String getEventListenerName(){
	return eventListenerName;
    }
    
    public void addEventService(String eventServiceName, X10EventListener eventService){
	logger.info("Event Service Manager - adding event service: " + eventServiceName);
	
	//Add the service to services map
	eventServices.put(eventServiceName, eventService);
    }

    public void removeEventService(String eventServiceName){

	//Remove the service from services map
	if(eventServices.containsKey(eventServiceName)){
	    eventServices.remove(eventServiceName);
	    logger.info("Event Service Manager - removing event service: " + eventServiceName + " - removed!");
	}
    }
    
    public X10EventListener getEventService(String eventServiceName){
	X10EventListener listener = null;
	if(eventServices.containsKey(eventServiceName)){
	    listener = eventServices.get(eventServiceName);
	}
	return listener;
    }

    public void startGUIManager(){
	    logger.info("Starting the GUI Manager");

	    GUIManager guiManager = new GUIManager(this,properties);
	    Thread thread = new Thread(guiManager);
	    thread.start();
	    eventServices.put(guiManager.getEventListenerName(), guiManager);
    }

    public void stopGUIManager(){
	if(eventServices.containsKey("GUIManager")){
	    eventServices.remove("GUIManager");
	}
    }
    
    public void startCM15A(){
	//Check to see if the CM15A interface has already been started
	if(!eventServices.containsKey(Interfaces.CM15A.toString())){
	    logger.info("Starting the CM15A Interface");
	    
	    CM15A cm15a = new CM15A(this);
	    Thread thread = new Thread(cm15a);
	    thread.start();
	    eventServices.put(cm15a.getEventListenerName(), cm15a);
	} else {
	    logger.info("CM15A already started");
	}
    }

    public void stopCM15A(){
	if(eventServices.containsKey(Interfaces.CM15A.toString())){
	    eventServices.remove(Interfaces.CM15A.toString());
	}
    }

    public void startCM19A(){
	//Check to see if the CM19A interface has already been started
	if(!eventServices.containsKey(Interfaces.CM19A.toString())){
	    logger.info("Starting the CM19A Interface");
	    
//	    CM19A cm19a = new CM19A(this);
//	    Thread thread = new Thread(cm19a);
//	    thread.start();
//	    eventServices.put(cm19a.getEventListenerName(), cm19a);
	} else {
	    logger.info("CM19A already started");
	}
    }

    public void stopCM19A(){
	if(eventServices.containsKey(Interfaces.CM19A.toString())){
	    eventServices.remove(Interfaces.CM19A.toString());
	}
    }

    public void startCM11A(String serialPort){
	//Check to see if the CM11A interface has already been started
	if(!eventServices.containsKey(Interfaces.CM11A.toString())){
	    logger.info("Starting the CM11A Interface");
	    
//	    CM11A cm11a = new CM11A(this);
//	    Thread thread = new Thread(cm11a);
//	    thread.start();
//	    eventServices.put(cm11a.getEventListenerName(), cm11a);
	} else {
	    logger.info("CM11A already started");
	}
    }
    
    public void stopCM11A(){
	if(eventServices.containsKey(Interfaces.CM11A.toString())){
	    eventServices.remove(Interfaces.CM11A.toString());
	}
    }

    public void startCM17A(String serialPort){
	//Check to see if the CM17A interface has already been started
	if(!eventServices.containsKey(Interfaces.CM17A.toString())){
	    logger.info("Starting the CM17A Interface");
	    
//	    CM17A cm17a = new CM17A(this);
//	    Thread thread = new Thread(cm17a);
//	    thread.start();
//	    eventServices.put(cm17a.getEventListenerName(), cm17a);
	} else {
	    logger.info("CM17A already started");
	}
    }
    
    public void stopCM17A(){
	if(eventServices.containsKey(Interfaces.CM17A.toString())){
	    eventServices.remove(Interfaces.CM17A.toString());
	}
    }

    public void startTCPConnectionManager(int port, int maxConnections){
	if(!eventServices.containsKey("TCPConnectionManager")){
    		logger.info("Starting the TCP Connection Manager");
    
    		TCPConnectionManager connectionManager = new TCPConnectionManager(this, port, maxConnections);
    		Thread thread = new Thread(connectionManager);
    		thread.start();
    		eventServices.put(connectionManager.getEventListenerName(), connectionManager);
	} else {
	    logger.info("TCP Connection Manager already started");
	}
    }

    public void stopTCPConnectionManager(){
	if(eventServices.containsKey("TCPConnectionManager")){
	    TCPConnectionManager tcpConnectionManager = (TCPConnectionManager)eventServices.get("TCPConnectionManager");
	    tcpConnectionManager.closeConnections();
	    eventServices.remove("TCPConnectionManager");
	}
    }
    
    public void startEventLogger(){
	if(!eventServices.containsKey("EventLogger")){
	    logger.info("Starting the Event Logger");

	    EventLogger eventLogger = new EventLogger();
	    eventServices.put(eventLogger.getEventListenerName(), eventLogger);
	} else {
	    logger.info("Event Logger already started");
	} 
    }
    
    public void stopEventLogger(){
	if(eventServices.containsKey("EventLogger")){
	    eventServices.remove("EventLogger");
	}
    }
}
